package org.mspring.platform.dao.hibernate;

import java.io.Serializable;
import java.util.List;
import org.hibernate.criterion.DetachedCriteria;
import org.mspring.platform.dao.DAOException;
import org.mspring.platform.dao.Page;
import org.mspring.platform.dao.hibernate.common.CriteriaQuery;
import org.mspring.platform.dao.hibernate.common.EnhancedRule;
import org.mspring.platform.dao.query.QueryBuilder;
import org.mspring.platform.utils.ClassUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;

/**
 *
 * @author Gao Youbo
 * @param <T>
 * @param <PK>
 * @since 2013-6-19
 */
@SuppressWarnings("unchecked")
public class GenericDao<T, PK extends Serializable> implements IGenericDao<T, PK> {

    protected final Logger log = LoggerFactory.getLogger(getClass());

    private DefaultHibernateTemplate hibernateTemplate;

    @Autowired
    public void setHibernateTemplate(DefaultHibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }

    protected DefaultHibernateTemplate getHibernateTemplate() {
        return hibernateTemplate;
    }

    protected JdbcTemplate getJdbcTemplate() {
        return hibernateTemplate.getJdbcTemplate();
    }

    private final Class<T> entityClass;

    public GenericDao() {
        this.entityClass = ClassUtils.getSuperClassGenricType(getClass(), 0);
    }

    @Override
    public List<T> listAll() {
        return (List<T>) hibernateTemplate.listAll(entityClass);
    }

    @Override
    public T get(PK id) {
        return hibernateTemplate.get(entityClass, id);
    }

    @Override
    public T getBy(String property, Object value) {
        return hibernateTemplate.getBy(entityClass, property, value);
    }

    @Override
    public void delete(T entity) throws DAOException {
        hibernateTemplate.delete(entity);
    }

    @Override
    public void delete(PK... id) {
        hibernateTemplate.delete(entityClass, id);
    }

    @Override
    public void update(T entity) {
        hibernateTemplate.update(entity);
    }

    @Override
    public List<T> list(String hql, Object... params) throws DAOException {
        return (List<T>) hibernateTemplate.list(hql, params);
    }

    @Override
    public List<T> list(QueryBuilder queryBuilder) {
        return hibernateTemplate.list(queryBuilder);
    }

    @Override
    public List<T> list(EnhancedRule enhancedRule) {
        return (List<T>) hibernateTemplate.list(entityClass, enhancedRule);
    }

    @Override
    public List<T> list(CriteriaQuery criteriaQuery) {
        return (List<T>) hibernateTemplate.list(criteriaQuery);
    }

    @Override
    public List<T> list(DetachedCriteria detachedCriteria) {
        return (List<T>) hibernateTemplate.findByCriteria(detachedCriteria);
    }

    @Override
    public List<T> list(DetachedCriteria detachedCriteria, int firstResult, int maxResults) {
        return (List<T>) hibernateTemplate.findByCriteria(detachedCriteria, firstResult, maxResults);
    }

    @Override
    public int executeUpdate(String hql, Object... params) throws DAOException {
        return hibernateTemplate.executeUpdate(hql, params);
    }

    @Override
    public T uniqueResult(String hql, Object... params) throws DAOException {
        return hibernateTemplate.uniqueResult(hql, params);
    }

    @Override
    public Page<T> listPage(QueryBuilder queryBuilder, Page<T> page) {
        return hibernateTemplate.listPage(queryBuilder, page);
    }

    @Override
    public Page<T> listPage(String hql, Page<T> page, Object... params) {
        return hibernateTemplate.listPage(hql, page, params);
    }

    @Override
    public Page<T> listPage(CriteriaQuery criteriaQuery, Page<T> page) {
        return hibernateTemplate.listPage(criteriaQuery, page);
    }

    @Override
    public T merge(T entity) {
        return hibernateTemplate.merge(entity);
    }

    @Override
    public PK insert(T entity) {
        return (PK) hibernateTemplate.save(entity);
    }

}
